#include "ThreadPool.h"
#include "Configuration.h"
#include "Crypto.h"
#include "Request.h"
#include "Response.h"
#include "Network.h"
#include "Task.h"
#include "DB.h"

#define SPACES " \t\n"

extern ThreadPool tpool;
extern Configuration conf; 

void do_register(void* arg, Thread* thread)
{
    // 1. 解析参数
    Param* param = (Param*) arg;
    int epfd = param->epfd;
    int connfd = param->connfd;
    // 用户名 密码
    char* username = strtok(param->req.value, SPACES);
    char* passwd = strtok(NULL, SPACES);
    printf("INFO: %s %s\n", username, passwd);

    // 2. 判断用户名是否已经被注册
    MYSQL* mysql = thread->mysql;

    Response resp;
    bzero(&resp, sizeof(resp));

    if (username_exist(mysql, username) > 0) {
        resp.status = RESP_EXIST;
        resp.length = 0;
    } else {
        register_username(mysql, username, passwd);
        resp.status = RESP_OK;
        resp.length = 0;
    }
    // 3. 发送响应
    int length = 2 * sizeof(int) + resp.length;
    send(connfd, &length, sizeof(int), MSG_WAITALL);
    send(connfd, &resp, length, MSG_WAITALL);
    // 4. 将connfd重新添加到epfd 
    epoll_add(epfd, connfd);
    free(arg);
}

void upload_file(void* arg, Thread* thread)
{
    // 1. 解析参数
    Param* param = (Param*) arg;
    // 文件大小 sha256sum  路径
    int epfd = param->epfd;
    int connfd = param->connfd;
    long fsize = atol(strtok(param->req.value, SPACES));
    const char* sha256sum = strtok(NULL, SPACES);
    const char* path = strtok(NULL, SPACES);
    printf("%ld %s %s\n", fsize, sha256sum, path);
    
    // 3. 判断文件是否已存在
    MYSQL* mysql = thread->mysql;
    char stmt[1024];
    sprintf(stmt, "SELECT * FROM files WHERE sha256sum = '%s'", sha256sum);
    mysql_query(mysql, stmt);

    MYSQL_RES* result = mysql_store_result(mysql); 
    unsigned long rows = mysql_num_rows(result);
    mysql_free_result(result);

    Response resp;
    if (rows != 0) {
        // 文件已存在，文件不需要再传
        resp.status = RESP_EXIST;
        resp.length = 0;

        int length = 2 * sizeof(int);
        send(connfd, &length, sizeof(int), MSG_WAITALL);
        send(connfd, &resp, length, MSG_WAITALL);
        return ;
    }
    // 文件不存在 
    resp.status = RESP_NOEXIST;
    resp.length = 0;
    int length = 2 * sizeof(int);
    send(connfd, &length, sizeof(int), MSG_WAITALL);
    send(connfd, &resp, length, MSG_WAITALL);

    // 接收文件
    int fd = open(sha256sum, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    char buf[4096];
    long nbytes = 0;
    while (nbytes < fsize) {
        int length = fsize - nbytes >= 4096 ? 4096 : fsize - nbytes;
        int n = recv(connfd, buf, length, MSG_WAITALL);
        if (n == -1) {
            // 发生错误
            fprintf(stderr, "recv(): %s\n", strerror(errno));
        } else if (n == 0) {
            // 对端断开连接
        } else {
            write(fd, buf, n);
            nbytes += n;
        }
    }

    epoll_add(epfd, connfd);
    free(arg);
    close(fd);
}
